package com.jike.shop.cloud.service;
import com.jike.shop.cloud.IOrderService;
import com.jike.shop.cloud.constant.RedisCommonPrefix;
import com.jike.shop.cloud.entity.OrderInfo;
import com.jike.shop.cloud.entity.OrderProduct;
import com.jike.shop.cloud.enums.OrderPayMethodEnum;
import com.jike.shop.cloud.enums.OrderStatusEnum;
import com.jike.shop.cloud.mapper.OrderInfoMapper;
import com.jike.shop.cloud.utils.RedisLock;
import com.jike.shop.common.dto.CreateOrderDTO;
import com.jike.shop.common.dto.GoodInfo;
import com.jike.shop.common.utils.SnowFlakeGenerateIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.junit.jupiter.api.Order;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;


import java.util.ArrayList;
import java.util.List;

@DubboService(group = "jike-shop",version = "1.0.0",protocol ="dubbo", delay = -1, cluster = "failfast", retries = 3, connections = 100, weight = 20)
@Slf4j
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private RedisLock redisLock;

//    @DubboReference(mock = "com.com.jike.shop.cloud.mock.RiskControlServiceMock")
//    private RiskControlService riskControlService;

    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private OrderProductService orderProductService;


    private static final String REDIS_KEY_PREFIX = RedisCommonPrefix.COMMON_PREFIX + "order:";
    private static final String CREATE_ORDER_LOCK_PREFIX =  REDIS_KEY_PREFIX + "lock:";

    //订单服务的Dubbo测试接口
    @Override
    public String test(Long id) {
        return "success";
    }

    String userId = "";

    @Override
    public Boolean createOrder(CreateOrderDTO requestDTO) {
        check(requestDTO);
        try {
            boolean locked = redisLock.lock(CREATE_ORDER_LOCK_PREFIX + requestDTO.getOrderId());
            if(!locked){
                log.debug("{}订单加锁失败", requestDTO.getOrderId());
                return false;
            }
            // 调用风控
            //riskControlService.riskVerification(userId);
            // 锁定优惠券
            // 确认促销信息
            // 锁定库存
            // 删减购物车
            // 创建订单
            this.saveOrderDb(requestDTO);
            return true;
        }catch (Exception e){
            log.info("{}创建异常，请稍后再试,{}", requestDTO.getOrderId(), e.getMessage());
            return false;
        }finally {
            redisLock.releaseLock(CREATE_ORDER_LOCK_PREFIX + requestDTO.getOrderId());
        }
    }

    private void check(CreateOrderDTO requestDTO) {
        if(OrderPayMethodEnum.getTarget(requestDTO.getPayInfo().getPaymentMethod()) == null){
            throw new RuntimeException("支付方式不正确！");
        }
    }

    @Override
    public Long preCreateOrder() {
        SnowFlakeGenerateIdWorker snowFlakeGenerateIdWorker = new SnowFlakeGenerateIdWorker(0L,0L);
        Long orderId = snowFlakeGenerateIdWorker.generateNextId();
        return orderId;
    }


    public void saveOrderDb(CreateOrderDTO requestDTO){
        OrderInfo orderInfo = assembleOrderInfo(requestDTO);
        List<OrderProduct> orderProducts = assembleOrderProduct(requestDTO);
        orderInfoService.save(orderInfo);
        orderProductService.saveBatch(orderProducts);
    }

    private OrderInfo assembleOrderInfo(CreateOrderDTO requestDTO){
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setParentOrderId(requestDTO.getOrderId());
        orderInfo.setOrderStatus(OrderStatusEnum.WAIT_PAYMENT);
        BeanUtils.copyProperties(requestDTO.getLogisticsInfo(), orderInfo);
        BeanUtils.copyProperties(requestDTO.getPriceInfo(), orderInfo);
        orderInfo.setPaymentMethod(OrderPayMethodEnum.getTarget(requestDTO.getPayInfo().getPaymentMethod()));
        BeanUtils.copyProperties(requestDTO.getInvoiceInfo(), orderInfo);
        return orderInfo;
    }
    private List<OrderProduct> assembleOrderProduct(CreateOrderDTO requestDTO){
        List<OrderProduct> products = new ArrayList<>();
        for(GoodInfo goodInfo : requestDTO.getGoodInfos()){
            OrderProduct orderProduct = new OrderProduct();
            BeanUtils.copyProperties(goodInfo, orderProduct);
            orderProduct.setParentOrderId(requestDTO.getOrderId());
            products.add(orderProduct);
        }
        return products;
    }




}
